/**
 * @module zane.mvc
 */
module zane.mvc
{
    /**
     * @class zane.mvc.Controller
     */
	export class Controller
	{
	
		////////////////////////////////////////////////////////////////////////////
        // protected static property
        ////////////////////////////////////////////////////////////////////////////
		
		public static controllerList:Controller[] = [];

		////////////////////////////////////////////////////////////////////////////
        //  private static methods
        ////////////////////////////////////////////////////////////////////////////
		
		private static hasController(cmd:string):boolean
		{
			var len:number = Controller.controllerList.length;
			for (var i:number = 0; i < len; ++i)
			{
				if (Controller.controllerList[i].cmd == cmd)
				{
					return true;
				}
			}
			return false;
		}
		
		private static removeController(cmd:String):boolean
		{
			var len:number = Controller.controllerList.length;
			for (var i:number = len - 1; i <= 0; ++i)
			{
				if (Controller.controllerList[i].cmd == cmd)
				{
					//注销附加操作
                    Controller.controllerList[i].onRemove();
                    Controller.controllerList[i] = null;
					//确保controller总是非空
                    Controller.controllerList.splice(i, 1);
					return true;
				}
			}
			return false;
		}

        public static notifyControllers(cmd:string, data:any = null, sponsor:any = null):void
        {
            var i:number = 0;
            while(i < Controller.controllerList.length)
            {
                if (Controller.controllerList[i].cmd == cmd)
                {
                    //执行一个或多个命令（FIFO）
                    Controller.controllerList[i].execute(data, sponsor);
                }
                i++;
            }
        }

		////////////////////////////////////////////////////////////////////////////
        // protected property
        ////////////////////////////////////////////////////////////////////////////

		public cmd:string;
		
		////////////////////////////////////////////////////////////////////////////
        //  constructor
        ////////////////////////////////////////////////////////////////////////////
		
		constructor(cmd:string)
		{
            if (Controller.hasController(cmd))
                throw new Error("Controller cmd [" + cmd + "] instance already constructed !");
            this.cmd = cmd;
            Controller.controllerList.push(this);
            this.onRegister();
		}

        ////////////////////////////////////////////////////////////////////////////
        //  public methods
        ////////////////////////////////////////////////////////////////////////////

        /**
         * 注册附加操作，需在子类中覆盖使用
         */
        public onRegister():void {  }

        /**
         * 注销附加操作，需在子类中覆盖使用
         */
        public onRemove():void { }

        /**
         * 执行Controller逻辑处理，需在子类中覆盖使用
         */
        public execute(data:any = null, sponsor:any = null):void { }

        public sendEvent(cmd:string, data:any = null, strict:boolean = false):void
        {
            if (!strict) View.notifyViews(cmd, data, this);
            Controller.notifyControllers(cmd, data, this);
        }

        public registerView(name:string, viewClass:IViewClass, viewComponent:Object):void
        {
            new viewClass(name, viewComponent);
        }

        public retrieveView(name:string):View
        {
            return View.retrieveView(name);
        }

        public removeView(name:string):void
        {
            View.removeView(name);
        }

        public registerController(cmd:string, controllClass:IControllerClass):void
        {
            new controllClass(cmd);
        }

        public removeController(cmd:string):void
        {
            Controller.removeController(cmd);
        }

        public registerModel(name:string, modelClass:IModelClass, data:any = null):void
        {
            new modelClass(name, data);
        }

        public retrieveModel(name:string):Model
        {
            return Model.retrieveModel(name);
        }

        public removeModel(name:string):void
        {
            Model.removeModel(name);
        }
	}
}